#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define RANGE(x, y, z) if(x >= y && x <= z)

typedef unsigned char uc;
typedef unsigned long long ull;

static const char *mode_prefix[] = {
    "",
    "0x",
    "0b",
};

ull hex2digit(const char *str)
{
    int n = 1;
    ull res = 0;
    for(int i = strlen(str) - 1; i >= 0; i--)
    {
        int t;
        RANGE(str[i], 'a', 'f')
            t = str[i] - 'a' + 10;
        else RANGE(str[i], 'A', 'F')
            t = str[i] - 'A' + 10;
        else RANGE(str[i], '0', '9')
            t = str[i] - '0';
        else
            t = 0;
#ifdef DEBUG
printf("%c: %d\n", str[i], t);
#endif
        res += t * n;
        n *= 16;
    }
    return res;
}

ull bin2digit(const char *str)
{
    int n = 1;
    ull res = 0;
    for(int i = strlen(str) - 1; i >= 0; i--)
    {
        int t;
        RANGE(str[i], '0', '1')
            t = str[i] - '0';
        else
            t = 0;

#ifdef DEBUG
printf("%c: %d\n", str[i], t);
#endif
        res += t * n;
        n *= 2;
    }
    return res;
}

const char *digit2str(int b, ull n)
{
    int buf_pos;
    static uc buf[128] = {};

    if(!n)
        return "0";

    if(b < 2 || b > 36)
        return NULL;

    buf_pos = sizeof(buf) - 2;
    while(n && buf_pos >= 0)
    {
        int t = n % b;
        buf[buf_pos] = t < 10 ? '0' + t : 'A' + (t - 10);
        n /= b;
        buf_pos--;
    }
    buf_pos++;

    return (const char*)buf + buf_pos;
}

int main(int argc, const char **argv)
{
    if(argc < 3) return 0;

    int mode = 0;       // 0 is dec, 1 is hex, 2 is bin
    int radix = 0;
    for(int i = 1; i < argc; i++)
    {
#ifdef DEBUG
printf("argv[%d]: %s\n", i, argv[i]);
#endif
        if(!strcmp("-h", argv[i]))
        {
            mode = 1;
            continue;
        }
        if(!strcmp("-d", argv[i]))
        {
            mode = 0;
            continue;
        }
        if(!strcmp("-b", argv[i]))
        {
            mode = 2;
            continue;
        }

        if(!radix)
        {
            radix = atoi(argv[i]);
        }
        else
        {
            ull n = mode ? ((mode == 1) ? hex2digit(argv[i]) : bin2digit(argv[i]))
                         : atoll(argv[i]);
            printf("%s%s: %s\n", mode_prefix[mode], argv[i], digit2str(radix, n));
        }
    }
    return 0;
}
